home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
420_01
/
pi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-21
|
16KB
|
725 lines
/*
// Pi.cc -- pi$@%U%)!<%^%C%H2hA|$r07$&(J
//
// created in 3/21/1993
// revised in 2/13/1994
*/
#include <stdio.h>
#include <stdlib.h>
#include "defs.h"
#include "Pi.h"
#include "Pic.h"
static unsigned char ColorTable[16 + 1][16 + 1];
static unsigned char *ColorTable256;
static int PreviousColor;
static int RestLength;
static unsigned char *Screen2;
static int PiMode;
static int PiXRatio, PiYRatio;
static int PiPlaneSize;
static int (*ReadColor)();
static void (*WriteColor)( int Previous, int Color );
void ExpandPi();
int PiReadLength();
int PiReadColor16();
int PiReadColor256();
void CompressPi();
void PiWriteLength( int n );
void PiWriteColor16( int Previous, int Color );
void PiWriteColor256( int Previous, int Color );
int Search( unsigned char *s1, int offset );
void ColorTableInitialize();
void PiLoad()
{
int i, OldWidth, x, y;
int Limit;
if ( fp == NULL && (fp = fopen( File, "rb" )) == NULL )
error ("%s: No such file");
AllocateBuffer();
BitBufferLength = 0;
PicBitLoad (8);
if ( PicWord != 'P' )
error ("%s: Is not pi format");
PicBitLoad (8);
if ( PicWord != 'i' )
error ("%s: Is not pi format");
for ( i = 0; i < 16384; i++ ) {
PicBitLoad (8);
if ( PicWord == 0x1a )
break;
}
if ( i == 16384 )
error ("%s: Is not pi format");
for ( i = 0; i < 16384; i++ ) {
PicBitLoad (8);
if ( PicWord == 0 )
break;
}
if ( i == 16384 )
error ("%s: Is not pi format");
PicBitLoad (8);
if ( (PiMode = PicWord) & ~0x80 )
error ("%s: Unknown pi-mode");
PicBitLoad (8);
PiXRatio = PicWord;
PicBitLoad (8);
PiYRatio = PicWord;
if ( PiXRatio == 0 || PiYRatio == 0 )
PiXRatio = PiYRatio = 1;
PicBitLoad (8);
if ( (PiPlaneSize = PicWord) != 4 && PiPlaneSize != 8 )
error ("%s: Irregal place size");
if ( PiPlaneSize == 8 ) {
if ( (ColorTable256 = (unsigned char*)malloc (65536 + 16)) == NULL )
error ("%s: Insufficient memory");
}
else
ColorTable256 = NULL;
PicBitLoad (8);
PicBitLoad (8);
PicBitLoad (8);
PicBitLoad (8);
PicBitLoad (16);
for ( i = PicWord; i > 0; i-- )
PicBitLoad (8);
PicBitLoad (16);
Width = PicWord;
PicBitLoad (16);
Height = PicWord;
if ( Screen != NULL )
free (Screen);
if ( (Screen = (int16*)malloc ((Size = Width * Height * PiXRatio * PiYRatio * 2) + 64)) == NULL )
error ("%s: Insufficient memory");
if ( (Screen2 = (unsigned char*)malloc (Width * (Height + 2) + 64)) == NULL )
error ("%s: Insufficient memory");
for ( i = 0; i < Width * (Height + 2); i++ )
Screen2[i] = 0;
if ( PiMode & 0x80 ) {
if ( PiPlaneSize == 4 ) {
for ( i = 0; i < 16; i++ ) {
Red[i] = ((i & 2)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
Green[i] = ((i & 4)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
Blue[i] = ((i & 1)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
}
}
else {
for ( i = 0; i < 256; i++ ) {
Red[i] = ((i >> 2) & 7) << 2;
Green[i] = (i >> 5) << 2;
Blue[i] = (i & 3) << 3;
}
}
}
else {
for ( i = 0; i < (1 << PiPlaneSize); i++ ) {
PicBitLoad (8);
Red[i] = PicWord >> 3;
PicBitLoad (8);
Green[i] = PicWord >> 3;
PicBitLoad (8);
Blue[i] = PicWord >> 3;
}
}
for ( i = 0; i < 256; i++ )
Palette[i] = (Red[i] << 5) | (Green[i] << 10) | Blue[i];
ColorTableInitialize();
ExpandPi();
Limit = Width * (Height + 2);
for ( i = Width * 2; i < Limit; i++ )
Screen[i - Width * 2] = Palette[Screen2[i]];
if ( PiXRatio != 1 || PiYRatio != 1 ) {
OldWidth = Width;
Width = Width * PiYRatio;
Height = Height * PiXRatio;
for ( y = Height - 1; y >= 0; y-- ) {
for ( x = Width - 1; x >= 0; x-- ) {
Screen[x + y * Width] = Screen[x / PiYRatio + (y / PiXRatio) * OldWidth];
}
}
}
if ( PiPlaneSize == 8 )
free (ColorTable256);
free (Screen2);
free (BitBuffer);
if ( fp != stdin )
fclose (fp);
if ( PiPlaneSize == 4 )
MaxColorGuaranteed = 16;
else
MaxColorGuaranteed = 256;
}
void PiSave()
{
int i, j;
int32 HalfSize, MaxColor;
for ( i = 0; i < 16; i++ )
Palette[i] = -1;
MaxColor = 0;
HalfSize = Size / 2;
if ( (Screen2 = (unsigned char*)malloc (Width * (Height + 2) + 16)) == NULL )
error ("%s: Insufficient memory");
for ( i = 0; i < HalfSize; i++ ) {
for ( j = 0; j < MaxColor; j++ )
if ( Palette[j] == Screen[i] )
break;
Screen2[i + Width * 2] = j;
if ( j == MaxColor ) {
Palette[j] = Screen[i];
MaxColor++;
if ( MaxColor > 256 )
error ("%s: Too many colors for pi format");
}
}
MaxColorGuaranteed = MaxColor;
if ( fp == NULL && (fp = fopen( File, "wb" )) == NULL )
error ("%s: No such file");
for ( i = 0; i < MaxColor; i++ ) {
Red[i] = ((Palette[i] >> 5) & 31) << 3;
Green[i] = (Palette[i] >> 10) << 3;
Blue[i] = (Palette[i] & 31) << 3;
}
AllocateBufferForWriting();
BitBufferLength = BitBufferSize;
BitLength = 8;
BitBufferPointer = BitBuffer;
if ( MaxColor <= 16 ) {
ColorTable256 = NULL;
PiPlaneSize = 4;
ColorTableInitialize();
PicBitWrite( 8, 'P' ); /* id; */
PicBitWrite( 8, 'i' );
PicBitWrite( 8, 26 ); /* eof; */
PicBitWrite( 8, 0 ); /* separator; */
PicBitWrite( 8, 0 ); /* mode; */
PicBitWrite( 8, 0 ); /* ratio; */
PicBitWrite( 8, 0 ); /* ratio; */
PicBitWrite( 8, 4 ); /* depth; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 16, 0 ); /* reserved size; */
PicBitWrite( 16, Width );
PicBitWrite( 16, Height );
for ( i = 0; i < 16; i++ ) {
PicBitWrite( 8, Red[i] );
PicBitWrite( 8, Green[i] );
PicBitWrite( 8, Blue[i] );
}
}
else {
if ( (ColorTable256 = (unsigned char*)malloc (65536 + 16)) == NULL )
error ("%s: Insufficient memory");
PiPlaneSize = 8;
ColorTableInitialize();
PicBitWrite( 8, 'P' ); /* id; */
PicBitWrite( 8, 'i' );
PicBitWrite( 8, 26 ); /* eof; */
PicBitWrite( 8, 0 ); /* separator; */
PicBitWrite( 8, 0 ); /* mode; */
PicBitWrite( 8, 0 ); /* ratio; */
PicBitWrite( 8, 0 ); /* ratio; */
PicBitWrite( 8, 8 ); /* depth; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 8, '-' ); /* machine code; */
PicBitWrite( 16, 0 ); /* reserved size; */
PicBitWrite( 16, Width );
PicBitWrite( 16, Height );
for ( i = 0; i < 256; i++ ) {
PicBitWrite( 8, Red[i] );
PicBitWrite( 8, Green[i] );
PicBitWrite( 8, Blue[i] );
}
}
CompressPi();
PicBufferWriteFlush();
if ( PiPlaneSize == 8 )
free (ColorTable256);
free (Screen2);
free (BitBuffer);
if ( fp != stdout )
fclose (fp);
}
void ColorTableInitialize()
{
int i, j;
if ( PiPlaneSize == 4 ) {
for ( j = 0; j < 16; j++ )
for ( i = 0; i < 16; i++ )
ColorTable[j][i] = (16 - i + j) & 15;
}
else {
for ( j = 0; j < 256; j++ )
for ( i = 0; i < 256; i++ )
ColorTable256[i + j * 256] = (256 - i + j);
}
}
void ExpandPi()
{
int i;
int c0, c1, c2, c3;
unsigned char *Screen3, *p;
int RestSize;
int PreviousPosition, Position, Length;
if ( PiPlaneSize == 4 )
ReadColor = PiReadColor16;
else
ReadColor = PiReadColor256;
PreviousColor = 0;
c0 = ReadColor();
c1 = ReadColor();
Screen3 = Screen2;
for ( i = 0; i < Width; i++ ) {
*Screen3++ = c0;
*Screen3++ = c1;
}
RestSize = Width * Height / 2;
for ( PreviousPosition = -1;; ) {
PicBitLoad (2);
if ( (Position = PicWord) == 3 ) {
PicBitLoad (1);
Position += PicWord;
}
if ( PreviousPosition == Position ) {
PreviousPosition = -1;
PreviousColor = *(Screen3 - 1);
for ( ;; ) {
*Screen3++ = ReadColor();
*Screen3++ = ReadColor();
RestSize--;
PicBitLoad (1);
if ( PicWord == 0 )
break;
}
continue;
}
PreviousPosition = Position;
if ( (Length = PiReadLength()) <= 0 )
continue;
if ( (RestSize -= Length) < 0 ) {
Length += RestSize;
RestSize = 0;
}
#define MoveMem(Source,Destination,Size) {\
unsigned